import { useEffect, useRef, useState } from 'react'
import moment from 'moment'
import { useStrategyBacktest, BASE_CAPITAL, useTradeMarkers } from './index'
import { calculateZIGLAG, calculateMT4ZigZag } from '../chart/indicators/ZIGLAG'

function update (chart, data) {
}

const comment = () => {
  return <div>基于ZIG ZAG折线的ZigLag策略。当ZIG ZAG从低点转向高点时买入，从高点转向低点时卖出。使用周期内的最高/最低点作为转折点。</div>
}

const INTERVAL_KEY = 'zigLagInterval'

const ZigLagTools = (props) => {
  const [started, setStarted] = useState(false)
  const [autoRun, setAutoRun] = useState(false)
  const [finished, setFinished] = useState(false)
  const [data, setData] = useState([])
  const [currentIndex, setCurrentIndex] = useState(0)
  const [holding, setHolding] = useState(false)
  const [intervalMs, setIntervalMs] = useState(() => {
    if (typeof window !== 'undefined') {
      const stored = localStorage.getItem(INTERVAL_KEY)
      if (stored) {
        const val = Number(stored)
        if (!Number.isNaN(val) && val >= 100 && val <= 5000) {
          return val
        }
      }
    }
    return 500
  })
  const intervalRef = useRef(intervalMs)
  const autoTimerRef = useRef(null)
  const tradeInfoRef = useRef({
    active: false,
    entryPrice: 0,
    entryTimestamp: null,
    entryIndex: -1,
    overlayId: null
  })
  const overlaysRef = useRef([])
  const { addTradeMarker, redrawTradeMarkers, clearTradeMarkers } = useTradeMarkers(props.chart)
  const {
    equityHistory,
    recordEquity,
    registerTrade,
    reset: resetBacktest,
    finalize,
    SummaryModal
  } = useStrategyBacktest()

  // 将 equityHistory 传递给父组件
  useEffect(() => {
    if (props.onEquityHistoryChange) {
      props.onEquityHistoryChange(equityHistory)
    }
  }, [equityHistory])

  useEffect(() => {
    return () => {
      if (autoTimerRef.current) {
        clearInterval(autoTimerRef.current)
      }
    }
  }, [])

  useEffect(() => {
    intervalRef.current = intervalMs
    if (typeof window !== 'undefined') {
      localStorage.setItem(INTERVAL_KEY, String(intervalMs))
    }
  }, [intervalMs])

  useEffect(() => {
    if (autoTimerRef.current) {
      clearInterval(autoTimerRef.current)
    }
    if (started && autoRun && !finished) {
      autoTimerRef.current = setInterval(() => {
        nextStep()
      }, intervalRef.current)
    }
    return () => {
      if (autoTimerRef.current) {
        clearInterval(autoTimerRef.current)
      }
    }
  }, [autoRun, started, finished, data, currentIndex])

  const removeTradeOverlay = () => {
    if (tradeInfoRef.current.overlayId && props.chart?.current) {
      try {
        props.chart.current.removeOverlay(tradeInfoRef.current.overlayId)
      } catch (e) {
        // ignore removal failures
      }
    }
    tradeInfoRef.current.overlayId = null
  }

  const loadRandomDataset = async () => {
    const stocks = props.stocks ?? []
    if (!stocks.length) {
      return
    }
    const tradable = stocks.filter(stock => {
      return ((stock.code.startsWith('60') && stock.code.endsWith('SH')) ||
        (stock.code.startsWith('00') && stock.code.endsWith('SZ')) ||
        (stock.code.startsWith('30') && stock.code.endsWith('SZ'))) &&
        !stock.name.includes('ST')
    })
    if (!tradable.length) {
      return
    }
    const randomStock = tradable[Math.floor(Math.random() * tradable.length)]
    const dates = (props.dates ?? []).filter(date => {
      return date / 1000 >= randomStock.open && moment.unix(date / 1000).year() <= 2021
    })
    if (!dates.length) {
      return
    }
    const randomDate = dates[Math.floor(Math.random() * dates.length)]
    const dailyData = await props.getKlines(randomStock.code, '1d', randomDate, 600)
    if (!dailyData || !dailyData.length) {
      return
    }
    // 从第50项开始回测（保留前50个数据用于指标计算）
    const startIndex = Math.min(50, dailyData.length - 1)
    const initialData = dailyData.slice(0, startIndex)
    setData(dailyData)
    setCurrentIndex(startIndex)
    setHolding(false)
    setFinished(false)
    removeTradeOverlay()
    clearTradeMarkers()
    tradeInfoRef.current = {
      active: false,
      entryPrice: 0,
      entryTimestamp: null,
      entryIndex: -1,
      overlayId: null
    }
    if (props.trader?.reset) {
      props.trader.reset()
    }
    resetBacktest()
    // 重置direction历史
    directionHistoryRef.current = []
    if (props.chart?.current && initialData.length > 0) {
      props.chart.current.applyNewData(initialData)
    }
    const initialTimestamp = initialData.length ? initialData[initialData.length - 1].timestamp : Date.now()
    recordEquity(initialTimestamp, props.trader?.equity ?? BASE_CAPITAL)
    setStarted(true)
    props.setInfoDisplay?.(false)
  }

  const nextStep = () => {
    if (finished || !started || data.length === 0) return
    
    const nextIndex = currentIndex + 1
    if (nextIndex >= data.length) {
      // 回测结束，强制平仓
      if (tradeInfoRef.current.active && tradeInfoRef.current.entryPrice) {
        const lastCandle = data[data.length - 1]
        const avgCostPrice = props.trader.sell(lastCandle.close)
        if (avgCostPrice && avgCostPrice > 0) {
          setHolding(false)
          addTradeMarker(lastCandle, 'sell', lastCandle.close)
          const entryPrice = tradeInfoRef.current.entryPrice
          const profitRatio = (lastCandle.close - avgCostPrice) / avgCostPrice
          if (!isNaN(profitRatio) && isFinite(profitRatio)) {
            registerTrade(profitRatio, avgCostPrice, lastCandle.close)
          }
        }
        tradeInfoRef.current = {
          active: false,
          entryPrice: 0,
          entryTimestamp: null,
          entryIndex: -1,
          overlayId: null
        }
        setTimeout(() => {
          setFinished(true)
          setAutoRun(false)
          finalize()
        }, 0)
        return
      }
      setFinished(true)
      setAutoRun(false)
      finalize()
      return
    }
    
    setCurrentIndex(nextIndex)
    const actualData = data.slice(0, nextIndex + 1)
    
    evaluateSignals(actualData)
    
    const candle = actualData[actualData.length - 1]
    if (!holding && !tradeInfoRef.current.active) {
      props.trader.hold(candle.close)
    }
    
    recordEquity(candle.timestamp, props.trader.equity)
    
    applyChart(actualData)
  }

  const refreshTradeOverlay = (actualData) => {
    const info = tradeInfoRef.current
    if (!info.active || !props.chart?.current) {
      removeTradeOverlay()
      return
    }
    if (info.entryIndex < 0 || info.entryIndex >= actualData.length) {
      removeTradeOverlay()
      return
    }
    const segment = actualData.slice(info.entryIndex)
    if (!segment.length) {
      removeTradeOverlay()
      return
    }
    // 使用全部数据的最高价和最低价，而不是只使用 segment 的价格
    const maxHigh = Math.max(...actualData.map(bar => bar.high))
    const minLow = Math.min(...actualData.map(bar => bar.low))
    const latestClose = segment[segment.length - 1].close
    const color = latestClose >= info.entryPrice ? 'rgba(255,22,22,0.15)' : 'rgba(13,190,28,0.15)'
    removeTradeOverlay()
    info.overlayId = props.chart.current.createOverlay({
      name: 'rect',
      styles: {
        polygon: {
          color
        }
      },
      points: [
        { timestamp: segment[0].timestamp, value: maxHigh },
        { timestamp: segment[segment.length - 1].timestamp, value: minLow }
      ]
    })
  }

  const createGhostBar = (last) => {
    if (!last) {
      return null
    }
    return {
      open: last.close,
      close: last.close,
      high: last.close,
      low: last.close,
      volume: 0,
      amount: 0,
      timestamp: last.timestamp + 24 * 60 * 60 * 1000
    }
  }

  // 绘制ZigLag指标的overlay（回测时使用）
  const ziggLagOverlaysRef = useRef([])
  
  const drawZiggLagOverlays = (actualData) => {
    if (!props.chart?.current || !actualData || actualData.length < 15) return
    
    // 从localStorage读取参数（与首页指标参数同步）
    let depth = 12, deviation = 5, backstep = 2, lineWidth = 2
    let lineUpColor = '#00ff00', lineDnColor = '#ff0000'
    try {
      const storedParams = localStorage.getItem('extraIndicators_params')
      if (storedParams) {
        const parsed = JSON.parse(storedParams)
        if (parsed?.ziggLag) {
          depth = parsed.ziggLag.depth ?? 12
          deviation = parsed.ziggLag.deviation ?? 5
          backstep = parsed.ziggLag.backstep ?? 2
          lineWidth = parsed.ziggLag.lineWidth ?? 2
          lineUpColor = parsed.ziggLag.lineUpColor ?? '#00ff00'
          lineDnColor = parsed.ziggLag.lineDnColor ?? '#ff0000'
        }
      }
    } catch (e) {
      console.warn('读取ZigLag参数失败', e)
    }
    
    // 清除之前的overlay
    ziggLagOverlaysRef.current.forEach(id => {
      try {
        props.chart.current.removeOverlay(id)
      } catch (e) {
        // ignore
      }
    })
    ziggLagOverlaysRef.current = []
    
    // 计算完整的 ZigZag
    const result = calculateMT4ZigZag(actualData, depth, deviation, backstep)
    if (!result || !result.points || result.points.length < 2) {
      return
    }
    
    // 绘制所有连接摆动点的线段
    const points = result.points
    for (let i = 0; i < points.length - 1; i++) {
      const point1 = points[i]
      const point2 = points[i + 1]
      
      const candle1 = actualData[point1.barIndex]
      const candle2 = actualData[point2.barIndex]
      
      if (!candle1 || !candle2) continue
      
      // 根据线段类型确定颜色：从低点到高点用上升色，从高点到低点用下降色
      const isUpward = point1.type === 'low' && point2.type === 'high'
      const color = isUpward ? lineUpColor : lineDnColor
      
      try {
        const lineId = props.chart.current.createOverlay({
          name: 'segment',
          points: [
            { timestamp: candle1.timestamp, value: point1.price },
            { timestamp: candle2.timestamp, value: point2.price }
          ],
          styles: {
            line: {
              color: color,
              size: lineWidth,
              style: 'solid'
            }
          }
        })
        
        if (lineId) {
          ziggLagOverlaysRef.current.push(lineId)
        }
      } catch (e) {
        console.warn('绘制ZigLag线段失败', e)
      }
    }
  }

  const applyChart = (actualData) => {
    if (!props.chart?.current) {
      return
    }
    if (!actualData.length) {
      props.chart.current.applyNewData([])
      props.onDataApplied?.([])
      return
    }
    const ghost = createGhostBar(actualData[actualData.length - 1])
    const chartData = ghost ? [...actualData, ghost] : [...actualData]
    props.chart.current.applyNewData(chartData)
    if (props.indicatorStrategies) {
      for (const indicatorStrategy of props.indicatorStrategies) {
        if (indicatorStrategy.reset) {
          indicatorStrategy.reset(props.chart.current)
        }
        indicatorStrategy.update(props.chart.current, chartData)
      }
    }
    // applyNewData 清除了所有 overlay，需要重新绘制买卖标记
    redrawTradeMarkers()
    
    // 绘制ZigLag指标overlay（回测时显示）
    drawZiggLagOverlays(actualData)
    
    props.onDataApplied?.(chartData)
    if (actualData.length) {
      const latest = actualData[actualData.length - 1]
      props.setPrice?.(latest.close)
    }
  }

  // 存储每个bar的direction和z2（用于检测direction != direction[1]）
  const directionHistoryRef = useRef([]) // [{ barIndex, direction, z1, z2 }]
  
  const evaluateSignals = (actualData) => {
    if (actualData.length < 30) return // 需要足够的数据计算指标
    
    const currIdx = actualData.length - 1
    const curr = actualData[currIdx]
    
    // 从localStorage读取参数（与首页指标参数同步）
    let depth = 12, deviation = 5, backstep = 2
    try {
      const storedParams = localStorage.getItem('extraIndicators_params')
      if (storedParams) {
        const parsed = JSON.parse(storedParams)
        if (parsed?.ziggLag) {
          depth = parsed.ziggLag.depth ?? 12
          deviation = parsed.ziggLag.deviation ?? 5
          backstep = parsed.ziggLag.backstep ?? 2
        }
      }
    } catch (e) {
      console.warn('读取ZigLag参数失败', e)
    }
    
    // 使用 MT4 ZigZag 算法计算当前bar的direction、z1、z2
    // 需要计算到当前bar为止的数据
    const result = calculateMT4ZigZag(actualData, depth, deviation, backstep)
    if (!result || !result.z2) return
    
    const currDirection = result.direction
    const currZ1 = result.z1
    const currZ2 = result.z2
    
    // 查找上一个bar的direction和z2（如果存在）
    const prevDirectionItem = directionHistoryRef.current.find(item => item.barIndex === currIdx - 1)
    const prevDirection = prevDirectionItem ? prevDirectionItem.direction : 0
    const prevZ2 = prevDirectionItem ? prevDirectionItem.z2 : null
    
    // 保存当前bar的direction和z2
    // 移除旧记录（如果有）
    directionHistoryRef.current = directionHistoryRef.current.filter(item => item.barIndex !== currIdx)
    directionHistoryRef.current.push({ 
      barIndex: currIdx, 
      direction: currDirection,
      z1: currZ1,
      z2: currZ2
    })
    
    // 检查是否确认了新的转折点（z2改变了）
    const z2Changed = !prevZ2 || (currZ2 && (
      currZ2.barIndex !== prevZ2.barIndex || 
      currZ2.price !== prevZ2.price
    ))
    
    // 关键逻辑：为了回测准确性，我们需要：
    // 1. 当确认新低点时买入（方向变化且确认了低点）
    // 2. 当确认新高点时卖出（不等到方向变化，立即在高点确认的bar卖出）
    // 3. 买入后立即开始overlay
    // 4. 确保不使用未来数据（所有使用的barIndex必须 < currIdx）
    
    // 优先检查卖出信号：如果确认了新高点，立即卖出（不等方向变化）
    // 判断逻辑：通过result.points确认z2的类型（high/low）
    if (holding && z2Changed && currZ2 && result.points && result.points.length > 0) {
      // 获取最后一个转折点的类型
      const lastPoint = result.points[result.points.length - 1]
      const isHighPoint = lastPoint.type === 'high'
      
      // 确保currZ2.barIndex < currIdx（避免未来函数）
      if (isHighPoint && currZ2.barIndex < currIdx) {
        // 确认了新高点，立即卖出（在高点确认的bar卖出）
        const sellBarIndex = currZ2.barIndex
        const tradeCandle = actualData[sellBarIndex]
        const tradePrice = tradeCandle ? tradeCandle.high : currZ2.price
        
        if (tradeCandle && sellBarIndex < currIdx) {
          const avgCostPrice = props.trader.sell(tradePrice)
          if (avgCostPrice && avgCostPrice > 0) {
            setHolding(false)
            addTradeMarker(tradeCandle, 'sell', tradePrice)
            if (tradeInfoRef.current.overlayId && props.chart?.current) {
              overlaysRef.current.push(tradeInfoRef.current.overlayId)
            }
            const entryPrice = tradeInfoRef.current.entryPrice
            const profitRatio = (tradePrice - avgCostPrice) / avgCostPrice
            if (!isNaN(profitRatio) && isFinite(profitRatio)) {
              registerTrade(profitRatio, avgCostPrice, tradePrice)
              console.log('✅ ZigLag 卖出（新高点确认）:', {
                entryPrice,
                avgCostPrice,
                exitPrice: tradePrice,
                profitRatio: ((tradePrice - avgCostPrice) / avgCostPrice * 100).toFixed(2) + '%',
                currZ2,
                prevZ2,
                sellBarIndex,
                currIdx,
                timestamp: tradeCandle.timestamp
              })
            }
            tradeInfoRef.current = {
              active: false,
              entryPrice: 0,
              entryTimestamp: null,
              entryIndex: -1,
              overlayId: null
            }
            // 卖出后刷新overlay（清除持仓区间）
            refreshTradeOverlay(actualData)
          }
        }
        return // 已卖出，不再检查买入信号
      }
    }
    
    // 检查买入信号：方向变化且确认了新的低点
    if (currDirection !== prevDirection && prevDirection !== 0) {
      if (currDirection > 0 && prevDirection < 0) {
        // 从下降转为上升：买入信号（对应原代码：direction != direction[1] and direction>0）
        // 使用前一个bar的z2价格（z2[1]），这是刚完成的转折点
        if (z2Changed && prevZ2 && prevZ2.barIndex < currIdx) {
          const tradePrice = prevZ2.price
          const tradeCandle = actualData[prevZ2.barIndex]
          
          if (!holding && tradeCandle) {
            props.trader.buy(tradePrice)
            setHolding(true)
            addTradeMarker(tradeCandle, 'buy', tradePrice)
            tradeInfoRef.current = {
              active: true,
              entryPrice: tradePrice,
              entryTimestamp: tradeCandle.timestamp,
              entryIndex: prevZ2.barIndex, // 使用prevZ2的barIndex，与tradeCandle一致
              overlayId: tradeInfoRef.current.overlayId
            }
            console.log('✅ ZigLag 买入:', {
              price: tradePrice,
              direction: 'bearish -> bullish',
              prevDirection,
              currDirection,
              prevZ2,
              currZ2,
              timestamp: tradeCandle.timestamp
            })
            // 买入后立即开始overlay
            refreshTradeOverlay(actualData)
          }
        }
      }
    }
    
    // 如果持仓中，持续更新overlay
    if (tradeInfoRef.current.active) {
      refreshTradeOverlay(actualData)
    }
  }

  const endBacktest = () => {
    setAutoRun(false)
    setFinished(true)
    finalize()
  }

  return (
    <>
      {SummaryModal}
      <div style={{
        display: 'flex',
        flexDirection: 'column',
        gap: 8,
        padding: '8px 12px',
        backgroundColor: 'rgba(26, 26, 26, 0.95)',
        borderRadius: 4
      }}>
        {!started ? (
          <button onClick={loadRandomDataset}>开始回测</button>
        ) : (
          <>
            <div style={{display: 'flex', gap: 8}}>
              <button onClick={nextStep} disabled={finished || autoRun}>步进</button>
              <button
                onClick={() => {
                  setAutoRun(prev => !prev)
                }}
              >
                {autoRun ? '停止自动' : '自动'}
              </button>
              <div style={{display: 'flex', alignItems: 'center', gap: 6}}>
                <div style={{color: 'rgba(255,255,255,0.65)', fontSize: 12}}>速度</div>
                <input
                  type="range"
                  min={100}
                  max={5000}
                  step={100}
                  value={intervalMs}
                  onChange={e => setIntervalMs(Number(e.target.value))}
                  style={{width: 160}}
                />
                <div style={{minWidth: 50, textAlign: 'right', color: '#0dd697', fontSize: 12}}>{(intervalMs / 1000).toFixed(1)}s</div>
              </div>
              <button onClick={endBacktest}>结束</button>
            </div>
          </>
        )}
      </div>
    </>
  )
}

export default { update, name: 'ZigLag', comment, Tools: ZigLagTools }

